﻿using System;
using System.Windows.Media.Imaging;
using Reactor.Entities;
using Reactor.Environment;
using Reactor.MiniManager.State;
using Reactor.ServiceGrid;

namespace Reactor.MiniManager.ViewModels
{
    public abstract class ServiceViewModelBase<T> : ViewModelBase where T : ServiceEntityBase
    {
        protected T ServiceEntity;
        private const string OnlineIndicatorPropertyName = "OnlineIndicator";

        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceViewModelBase&lt;T&gt;"/> class.
        /// </summary>
        protected ServiceViewModelBase(T serviceEntity)
        {
            if (serviceEntity == null) throw new ArgumentNullException("serviceEntity");
            ServiceEntity = serviceEntity;
        }

        public string Name
        {
            get { return ServiceEntity.Identifier.Name; }
            set
            {
                if (ServiceEntity.Identifier.Name == value) return;

                ServiceEntity.Identifier.Name = value;
                OnPropertyChanged("Name");
            }
        }

        public Version Version
        {
            get { return ServiceEntity.Identifier.Version; }
            set
            {
                if (ServiceEntity.Identifier.Version == value) return;

                ServiceEntity.Identifier.Version = value;
                OnPropertyChanged("Version");
            }
        }

        public ServiceIdentifier Identifier
        {
            get { return ServiceEntity.Identifier; }
        }

        public T Entity
        {
            get
            {
                return ServiceEntity;
            }
        }

        public object StatusIndicator
        {
            get
            {
                switch (GetStatus())
                {
                    case ServiceStatus.Unknown:
                        return new BitmapImage(new Uri(@"pack://application:,,,/Images/StatusLight-Disabled.png", UriKind.Absolute));
                    case ServiceStatus.Online:
                        return new BitmapImage(new Uri(@"pack://application:,,,/Images/StatusLight-Green.png", UriKind.Absolute));
                    case ServiceStatus.Offline:
                        return new BitmapImage(new Uri(@"pack://application:,,,/Images/StatusLight-Red.png", UriKind.Absolute));
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }

        public DateTime LastSeen
        {
            get { return ServiceEntity.LastSeen; }
            set
            {
                if (ServiceEntity.LastSeen == value) return;

                ServiceEntity.LastSeen = value;
                OnPropertyChanged("LastSeen");
                OnPropertyChanged(OnlineIndicatorPropertyName);
            }
        }

        private ServiceStatus GetStatus()
        {
            var coreStateCache = Context.ServiceLocator.GetInstance<ICoreStateCache>();

            return (DateTime.Now - ServiceEntity.LastSeen) > coreStateCache.HealthCheckInterval
                ? ServiceStatus.Offline
                : ServiceStatus.Online;
        }
    }
}
